import { scorePoint } from "../utils/dataMap";
const { baseUrl } = require('../utils/baseUrl.js');
const app = getApp()
let recorderManager = null
let innerAudioContext = null
let socketTask = null

module.exports = Behavior({
  /**
   * 组件的属性列表
   */
  properties: {
    practiceId: {
      type: String,
      observer (practiceId) {
        this.setData({
          talkList: []
        })
      }
    },
    sceneType: String,
    countdown: {
      type: Boolean,
      observer (show) {
        if (show) {
          this.setData({
            connectTimes: 0,
          })
          this.connectSocket()
        }
      }
    },
    practiceShow: {
      type: Boolean,
      observer (show) {
        if (show) {
          this.setData({
            tipShow: true
          })
          const startSocket = () => {
            if (socketTask.readyState === 1) {
              socketTask.send({data: 'WS_START'})
            }
          }
          wx.getSetting({
            success: (res) => {
              if (!res.authSetting['scope.record']) {
                console.log(123)
                wx.authorize({
                  scope: 'scope.record',
                  success: () => {
                    // 用户已经同意小程序使用录音功能，后续调用 wx.startRecord 接口不会弹窗询问
                    startSocket()
                    this.setData({recorderAllow: true})
                  },
                  fail: () => {
                    wx.showModal({
                      content: '检测到您没有打开麦克风权限，是否去设置打开?',
                      cancelColor: '#666666',
                      cancelText: '取消',
                      confirmText: '确认',
                      confirmColor: '#006DE7',
                      success (res) {
                        if (res.confirm) {
                          wx.openSetting({
                            success: res => {
    
                            }
                          })
                        } else if (res.cancel) {
                          
                        }
                      }
                    })
                    startSocket()
                  }
                })
              } else {
                startSocket()
                this.setData({recorderAllow: true})
              }
            }
          })
        } else {
          socketTask.close()
          socketTask = null
        }
      }
    },
  },

  /**
   * 组件的初始数据
   */
  data: {
    hasExamPower:false,
    CDNPATH: app.globalData.CDNPATH,
    talkList: [],
    tipShow: true, // 提示展示
    recording: false, // 是否录音中
    connectTimes: 0, // websocket连接次数
    recordDisabled: false,
    scrollTop: 0,
    detail: '我的结局大家都觉得大家倒角机倒角倒角倒角',
    canPlay: true, // 音频能否播放,若离开或隐藏页面则不能
    recorderAllow: false, // 是否授权麦克风
    isEnd: false, // 陪练结束
  },
  options: {
    addGlobalClass: true,
    multipleSlots: true,
  },
  ready () {
    const self = this
    wx.setInnerAudioOption({
      obeyMuteSwitch: false
    })
    recorderManager = wx.getRecorderManager()
    recorderManager.onStart(() => {
      console.log('recorder start')
      self.setData({
        recording: true
      })
    })
    recorderManager.onPause(() => {
      console.log('recorder pause')
    })
    recorderManager.onStop((res) => {
      setTimeout(() => {
        console.log('录音结束发送消息', new Date())
        socketTask.send({data: 'END_SOUND_RECORDING'})
      }, 1000);
      self.setData({
        recording: false
      })
      const { tempFilePath } = res
    })
    recorderManager.onFrameRecorded((res) => {
      const { frameBuffer } = res
      socketTask.send({
        data: frameBuffer,
        success: (e) => {
          // console.log(e)
        },
        fail: (err) => {
          console.log(err)
        },
        complete: (res) => {
          // console.log(res)
        },
      })
      // console.log('frameBuffer', frameBuffer)
    })

    // 播放监听避免重复绑定
    innerAudioContext = wx.createInnerAudioContext()
    innerAudioContext.onCanplay(() => {
      console.log('can play')
    })
    innerAudioContext.onPlay(() => {
      console.log('开始播放')
      this.setData({
        recordDisabled: true
      })
      this.stop()
    })
    innerAudioContext.onEnded(() => {
      console.log('播放结束')
      this.setData({
        recordDisabled: false
      })
      wx.getFileSystemManager()
      .unlink({
        filePath: innerAudioContext.src
      })
      console.log(this.data.isEnd)
      if (this.data.isEnd) {
        this.trainEnd()
      }
    })
    innerAudioContext.onError((res) => {
      console.log(res.errMsg)
      console.log(res.errCode)
      if (this.data.isEnd) {
        this.trainEnd()
      }
    })
    this.setData({
      imgResUrl: app.globalData.userInfo.imgResUrl
    })
    const permissionCodes = app.globalData.permissionCodes || []
    const hasPower = permissionCodes.includes('customs_clearance')
    this.setData({
      hasExamPower:hasPower
    })
  },
  detached () {
    if (this.data.recording) {
      // 不判断会弹2次授权
      this.stop()
    }
    socketTask && socketTask.close()
    socketTask = null
    innerAudioContext && innerAudioContext.pause()
    this.setData({
      recordDisabled: false,
      canPlay: false
    })
  },
  pageLifetimes: {
    show: function() {
      // 页面被展示
      this.setData({
        canPlay: true
      })
      if (this.data.isEnd) {
        this.trainEnd()
      }
    },
    hide: function() {
      // 页面被隐藏
      if (this.data.recording) {
        this.stop()
      }
      // socketTask.close()
      innerAudioContext.pause()
      this.setData({
        recordDisabled: false,
        canPlay: false
      })
    },
    resize: function(size) {
      // 页面尺寸变化
    },
  },
  /**
   * 组件的方法列表
   */
  methods: {
    handleRecord: function () {
      const recordOrNot = () => {
        if (this.data.recording) {
          // setTimeout(() => {
            this.stop()
          // }, 500);
        } else {
          this.record()
        }
      }
      if (this.data.recorderAllow) {
        recordOrNot()
      } else {
        // 弹窗授权
        wx.getSetting({
          success: (res) => {
            if (!res.authSetting['scope.record']) {
              wx.showModal({
                content: '检测到您没有打开麦克风权限，是否去设置打开?',
                cancelColor: '#666666',
                cancelText: '取消',
                confirmText: '确认',
                confirmColor: '#006DE7',
                success (res) {
                  if (res.confirm) {
                    wx.openSetting({
                      success: res => {
                      }
                    })
                  }
                }
              })
            } else {
              this.setData({recorderAllow: true})
              recordOrNot()
            }
          }
        })
      }
    },
    record: function () {
      const options = {
        duration: 600000,
        sampleRate: 16000,
        numberOfChannels: 1,
        encodeBitRate: 96000,
        format: 'pcm',
        frameSize: 1
      }
      recorderManager.start(options)
    },
    stop: function () {
      console.log('停止开始', new Date())
      recorderManager.stop()
    },
    toggleTips (e) {
      this.setData({
        tipShow: e.detail.value
      })
    },
    connectSocket: function () {
      const { practiceId, sceneType, connectTimes } = this.data
      const options = {
        url: `wss://${baseUrl}/nls/nls/websocket/${practiceId}/${wx.getStorageSync("token")}/${connectTimes}/${sceneType}`,
        success: (resConnect) => {
          console.log('连接成功')
        },
        fail: (resConnectError) => {
          console.log('连接失败')
        },
      }
      this.setData({
        isEnd: false
      })
      console.log(options.url, this.data.isEnd)
      socketTask = wx.connectSocket(options)
      socketTask.onOpen(() => {
        console.log('握手成功')
      })
      socketTask.onMessage((e) => {
        if (typeof e.data === 'string') {
          const data = JSON.parse(e.data)
          console.log(data, '收到消息', new Date())
          var queryHeight = this.createSelectorQuery();
          queryHeight.select('#scrollViewHieght').boundingClientRect();
          var self = this
          queryHeight.exec(function(res) {
            self.setData({
              scrollTop: self.data.scrollTop + (res[0].height)
            })
          })
          // console.log(data)
          let { talkList } = this.data
          if (data.userMessage) {
            // 用户说话
            talkList.length - 3 >= 0 && (talkList[talkList.length - 3].retryDisabled = true) // 说话后上一句就不能重练了
            talkList[talkList.length - 1].word = data.userMessage
            this.setData({
              talkList,
            })
            // this.triggerEvent('setPlayIdx', { index: talkList.length - 1 }, {})
          }
          if (data.nodeDeductInfos && data.nodeDeductInfos.length > 0) {
            // 评分详情
            data.nodeDeductInfos.map((j, o) => {
              j.ruleName = scorePoint[j.ruleType]
            })
            talkList[talkList.length - 1].open = false
            talkList[talkList.length - 1].nodeDeductInfos = data.nodeDeductInfos
            this.setData({ talkList })
          }
          if (data.robotMessage
            && (talkList.length === 0 || talkList[talkList.length - 1].word)) {
            // 机器人说话&&不是重连
            talkList.push({
              role: 'robot',
              word: data.robotMessage,
            })
            this.setData({
              talkList,
            })
            // this.triggerEvent('setPlayIdx', { index: talkList.length - 1 }, {})
          }
          if (data.recAnswer
            && (talkList.length === 0 || talkList[talkList.length - 1].word)
            && !data.isEnd
            && !data.userMessage) {
            // 提示，重连表示'我'未说话，无需显示多条提示
            talkList.push({
              role: 'customer',
              tips: data.recAnswer,
              points: data.name
            })
            this.setData({
              talkList
            })
          }
          if (data.isEnd === true) {
            console.log('isEnd', new Date())
            // 结束后加1，使进度条完成
            this.setData({
              isEnd: true
            })
            if (!data.robotMessage) {
              this.trainEnd()
            }
          }
          this.triggerEvent('setPlayIdx', { index: talkList.length }, {})
        } else {
          console.log(e.data)
          this.getUrl(e.data)
          
        }
      })
      socketTask.onError((e) => {
        console.log('连接失败', e)
      })
      socketTask.onClose((e) => {
        console.log('连接关闭', e, new Date())
        this.reConnect()
      })
    },
    reConnect () {
      const { connectTimes } = this.data
      if (socketTask && socketTask.readyState !== 1) {
        console.log('重连')
        if (connectTimes > 20) {
          wx.showToast({
            title: '网络开小差了，请返回重新进入',
            icon: 'none',
            duration: 1000,
          })
        } else {
          wx.showToast({
            title: '正在重新连接',
            icon: 'none',
            duration: 500,
            complete: () => {
              this.setData({
                connectTimes: connectTimes + 1
              })
              this.connectSocket()
            }
          })
        }
      }
    },
    trainEnd () {
      this.triggerEvent('trainEnd', {}, {})
      socketTask && socketTask.close()
      socketTask = null
    },
    getUrl: function (url) {
      const filePath = `${wx.env.USER_DATA_PATH}/temp_${new Date().getTime()}.wav`
      wx.getFileSystemManager()
      .writeFile({
        filePath,
        data: url,
        encoding: 'binary',
        success: res => {
          console.log(filePath)
          const { canPlay } = this.data
          console.log(this.data.isEnd)
          if (canPlay) {
            innerAudioContext.autoplay = true
            innerAudioContext.src = filePath
            innerAudioContext.play()
          }
        },
        fail: res => {
          console.log('fail')
          console.log(res)
        }
      })
    },
    tryAgain (e) {
      const { index } = e.currentTarget.dataset
      let { talkList } = this.data
      talkList = talkList.slice(0, talkList.length - 2)
      talkList[talkList.length - 1] = {
        role: 'customer',
        tips: talkList[talkList.length - 1].tips,
        points: talkList[talkList.length - 1].points,
      }
      this.setData({ talkList, recordDisabled: false })
      innerAudioContext.pause()
      socketTask.send({data: 'REPEAT'})
    },
    toggleScore (e) {
      const { index } = e.currentTarget.dataset
      const { open } = this.data.talkList[index]
      this.setData({
        [`talkList[${index}].open`]: !open
      })
    },
    close () {
      this.triggerEvent('close', {}, {})
      innerAudioContext && innerAudioContext.pause()
      innerAudioContext = null
    },
  }
})